﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;

namespace YJKDragCurveJig
{
	public class JigGeometry
	{
		public static bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		public static bool LessThan(double val1, double val2, double eps)
		{
			return val1 - val2 < -eps;
		}

		public static bool GreaterThan(double val1, double val2)
		{
			return val1 - val2 > 1E-09;
		}

		public static bool GreaterThan(double val1, double val2, double eps)
		{
			return val1 - val2 > eps;
		}

		public static bool IsEqual(double val1, double val2)
		{
			return !JigGeometry.LessThan(val1, val2) && !JigGeometry.LessThan(val2, val1);
		}

		public static bool IsEqual(double val1, double val2, double eps)
		{
			return !JigGeometry.LessThan(val1, val2, eps) && !JigGeometry.LessThan(val2, val1, eps);
		}

		public static bool Lessthan_Or_Equal(double val1, double val2)
		{
			return !JigGeometry.GreaterThan(val1, val2);
		}

		public static bool Lessthan_Or_Equal(double val1, double val2, double eps)
		{
			return !JigGeometry.GreaterThan(val1, val2, eps);
		}

		public static bool Greaterthan_Or_Equal(double val1, double val2)
		{
			return !JigGeometry.LessThan(val1, val2);
		}

		public static bool Greaterthan_Or_Equal(double val1, double val2, double eps)
		{
			return !JigGeometry.LessThan(val1, val2, eps);
		}

		public static bool IsParallel(XYZ a, XYZ b)
		{
			double num = a.AngleTo(b);
			return 1E-09 > num || JigGeometry.IsEqual(num, Math.PI);
		}

		public static bool IsVertical(XYZ a, XYZ b)
		{
			return JigGeometry.IsEqual(a.AngleTo(b), Math.PI*.5);
		}

		public static XYZ RotateTo(XYZ pt, double angle, XYZ axis)
		{
			Transform transform = RevitVersionFuncs.CreateRotationAtPoint(axis, angle, new XYZ(0.0, 0.0, 0.0));
			return JigGeometry.TransformPoint(pt, transform);
		}

		public static XYZ CalculateFootPoint(Line line, XYZ point)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			return JigGeometry.CalculateFootPoint(hyendPoint, hyendPoint2, point);
		}

		public static XYZ CalculateFootPoint(XYZ ptStart, XYZ ptEnd, XYZ point)
		{
			double num = Math.Sqrt((ptEnd.X - ptStart.X) * (ptEnd.X - ptStart.X) + (ptEnd.Y - ptStart.Y) * (ptEnd.Y - ptStart.Y) + (ptEnd.Z - ptStart.Z) * (ptEnd.Z - ptStart.Z));
			num = ((ptEnd.X - ptStart.X) * (point.X - ptStart.X) + (ptEnd.Y - ptStart.Y) * (point.Y - ptStart.Y) + (ptEnd.Z - ptStart.Z) * (point.Z - ptStart.Z)) / (num * num);
			double num2 = ptStart.X + (ptEnd.X - ptStart.X) * num;
			double num3 = ptStart.Y + (ptEnd.Y - ptStart.Y) * num;
			double num4 = ptStart.Z + (ptEnd.Z - ptStart.Z) * num;
			return new XYZ(num2, num3, num4);
		}

		public static XYZ CalculateFootPoint(Arc arc, XYZ point)
		{
			XYZ center = arc.Center;
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ hyendPoint2 = arc.GetEndPoint(1);
			return JigGeometry.CalculateFootPoint(hyendPoint, hyendPoint2, center, point);
		}

		public static XYZ CalculateFootPoint(XYZ ptStart, XYZ ptEnd, XYZ ptCenter, XYZ point)
		{
			double num = ptCenter.DistanceTo(ptStart);
			XYZ xyz = new XYZ(point.X, point.Y, ptCenter.Z) - ptCenter;
			xyz = xyz.Normalize() * num;
			return ptCenter + xyz;
		}

		public static bool PointAtLineLeft(XYZ pt, XYZ ptStart, XYZ ptEnd)
		{
			double num = ptEnd.Y - ptStart.Y;
			double num2 = ptStart.X - ptEnd.X;
			double num3 = ptEnd.X * ptStart.Y - ptStart.X * ptEnd.Y;
			return num * pt.X + num2 * pt.Y + num3 < 0.0;
		}

		public static XYZ TransformPoint(XYZ point, Transform transform)
		{
			double x = point.X;
			double y = point.Y;
			double z = point.Z;
			XYZ xyz = transform.get_Basis(0);
			XYZ xyz2 = transform.get_Basis(1);
			XYZ xyz3 = transform.get_Basis(2);
			XYZ origin = transform.Origin;
			double num = x * xyz.X + y * xyz2.X + z * xyz3.X + origin.X;
			double num2 = x * xyz.Y + y * xyz2.Y + z * xyz3.Y + origin.Y;
			double num3 = x * xyz.Z + y * xyz2.Z + z * xyz3.Z + origin.Z;
			return new XYZ(num, num2, num3);
		}

		public static XYZ TransformPointToShaftSide(XYZ point, double angle)
		{
			double num = point.X + point.Y * Math.Cos(angle / 180.0 * Math.PI);
			double num2 = point.Y * Math.Sin(angle / 180.0 * Math.PI) + point.Z;
			return new XYZ(num, num2, point.Z);
		}

		public static BoundingBoxUV CalculateBoundingBox2D(XYZ ptStart, XYZ ptEnd)
		{
			double x = ptStart.X;
			double x2 = ptEnd.X;
			double y = ptStart.Y;
			double y2 = ptEnd.Y;
			if (x > x2)
			{
				x = ptEnd.X;
				x2 = ptStart.X;
			}
			if (y > y2)
			{
				y = ptEnd.Y;
				y2 = ptStart.Y;
			}
			return new BoundingBoxUV(x, y, x2, y2);
		}

		public static BoundingBoxUV CalculateBoundingBox2D(Line line)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			return JigGeometry.CalculateBoundingBox2D(hyendPoint, hyendPoint2);
		}

		public static void GetArcAngles(Arc arc, ref double startAngle, ref double endAngle)
		{
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ hyendPoint2 = arc.GetEndPoint(1);
			XYZ center = arc.Center;
			startAngle = XYZ.BasisX.AngleOnPlaneTo(hyendPoint - center, XYZ.BasisZ);
			endAngle = XYZ.BasisX.AngleOnPlaneTo(hyendPoint2 - center, XYZ.BasisZ);
			if (JigGeometry.IsEqual(arc.Normal.Z, -1.0))
			{
				endAngle = (double)((float)XYZ.BasisX.AngleOnPlaneTo(hyendPoint - center, XYZ.BasisZ));
				startAngle = (double)((float)XYZ.BasisX.AngleOnPlaneTo(hyendPoint2 - center, XYZ.BasisZ));
			}
			if (startAngle > endAngle)
			{
				startAngle -= Math.PI*2;
			}
		}

		public static BoundingBoxUV CalculateBoundingBox2D(XYZ ptStart, XYZ ptEnd, XYZ ptCenter, XYZ normal, double radius)
		{
			double num = ptStart.X;
			double num2 = ptEnd.X;
			double num3 = ptStart.Y;
			double num4 = ptEnd.Y;
			if (num > num2)
			{
				num = ptEnd.X;
				num2 = ptStart.X;
			}
			if (num3 > num4)
			{
				num3 = ptEnd.Y;
				num4 = ptStart.Y;
			}
			XYZ pt = ptCenter + XYZ.BasisX * radius;
			if (JigGeometry.Is_Point_OnSegment(ptStart, ptEnd, ptCenter, normal, pt))
			{
				num2 = ptCenter.X + radius;
			}
			XYZ pt2 = ptCenter - XYZ.BasisX * radius;
			if (JigGeometry.Is_Point_OnSegment(ptStart, ptEnd, ptCenter, normal, pt2))
			{
				num = ptCenter.X - radius;
			}
			XYZ pt3 = ptCenter + XYZ.BasisY * radius;
			if (JigGeometry.Is_Point_OnSegment(ptStart, ptEnd, ptCenter, normal, pt3))
			{
				num4 = ptCenter.Y + radius;
			}
			XYZ pt4 = ptCenter - XYZ.BasisY * radius;
			if (JigGeometry.Is_Point_OnSegment(ptStart, ptEnd, ptCenter, normal, pt4))
			{
				num3 = ptCenter.Y - radius;
			}
			return new BoundingBoxUV(num, num3, num2, num4);
		}

		public static BoundingBoxUV CalculateBoundingBox2D(Arc arc)
		{
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ hyendPoint2 = arc.GetEndPoint(1);
			XYZ center = arc.Center;
			XYZ normal = arc.Normal;
			double radius = arc.Radius;
			if (arc.IsCyclic && !arc.IsBound)
			{
				return new BoundingBoxUV(center.X - radius, center.Y - radius, center.X + radius, center.Y + radius);
			}
			return JigGeometry.CalculateBoundingBox2D(hyendPoint, hyendPoint2, center, normal, radius);
		}

		public static BoundingBoxUV BoundingBoxesMerge(BoundingBoxUV box1, BoundingBoxUV box2)
		{
			BoundingBoxUV boundingBoxUV = new BoundingBoxUV();
			double u = box1.Min.U;
			double v = box1.Min.V;
			double u2 = box1.Max.U;
			double v2 = box1.Max.V;
			UV min = box2.Min;
			UV max = box2.Max;
			if (min.U < u)
			{
				u = min.U;
			}
			if (min.V < v)
			{
				v = min.V;
			}
			boundingBoxUV.Min = new UV(u, v);
			if (max.U > u2)
			{
				u2 = max.U;
			}
			if (max.V > v2)
			{
				v2 = max.V;
			}
			boundingBoxUV.Max = new UV(u2, v2);
			return boundingBoxUV;
		}

		public static BoundingBoxXYZ BoundingBoxesMerge(BoundingBoxXYZ box1, BoundingBoxXYZ box2)
		{
			BoundingBoxXYZ boundingBoxXYZ = new BoundingBoxXYZ();
			double x = box1.Min.X;
			double y = box1.Min.Y;
			double z = box1.Min.Z;
			double x2 = box1.Max.X;
			double y2 = box1.Max.Y;
			double z2 = box1.Max.Z;
			XYZ min = box2.Min;
			XYZ max = box2.Max;
			if (min.X < x)
			{
				x = min.X;
			}
			if (min.Y < y)
			{
				y = min.Y;
			}
			if (min.Z < z)
			{
				z = min.Z;
			}
			boundingBoxXYZ.Min = new XYZ(x, y, z);
			if (max.X > x2)
			{
				x2 = max.X;
			}
			if (max.Y > y2)
			{
				y2 = max.Y;
			}
			if (max.Z > z2)
			{
				z2 = max.Z;
			}
			boundingBoxXYZ.Max = new XYZ(x2, y2, z2);
			return boundingBoxXYZ;
		}

		public static XYZ CalculatMidPoint(XYZ ptStart, XYZ ptEnd)
		{
			XYZ xyz = ptEnd - ptStart;
			return ptStart + xyz / 2.0;
		}

		public static XYZ CalculatMidPoint(Line line)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			return JigGeometry.CalculatMidPoint(hyendPoint, hyendPoint2);
		}

		public static XYZ CalculatMidPoint(XYZ ptStart, XYZ ptEnd, XYZ ptCenter, XYZ normal)
		{
			if (normal.Z < 0.0)
			{
				XYZ xyz = ptStart;
				ptStart = ptEnd;
				ptEnd = xyz;
			}
			XYZ xyz2 = ptStart - ptCenter;
			double length = xyz2.GetLength();
			XYZ pt = xyz2.Normalize();
			double num = XYZ.BasisX.AngleOnPlaneTo(ptStart - ptCenter, XYZ.BasisZ);
			double num2 = XYZ.BasisX.AngleOnPlaneTo(ptEnd - ptCenter, XYZ.BasisZ);
			if (num > num2)
			{
				num -= Math.PI*2;
			}
			double angle = (num2 - num) / 2.0;
			XYZ xyz3 = JigGeometry.RotateTo(pt, angle, XYZ.BasisZ).Normalize();
			return ptCenter + xyz3 * length;
		}

		public static XYZ CalculatMidPoint(Arc arc)
		{
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ center = arc.Center;
			XYZ pt = (hyendPoint - center).Normalize();
			double radius = arc.Radius;
			double num = arc.Length / radius / 2.0;
			XYZ xyz = JigGeometry.RotateTo(pt, num, XYZ.BasisZ).Normalize();
			if (JigGeometry.IsEqual(arc.Normal.Z, -1.0))
			{
				xyz = JigGeometry.RotateTo(pt, -num, XYZ.BasisZ).Normalize();
			}
			return center + xyz * radius;
		}

		public static Line OffsetLine(Line line, double offset)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			XYZ xyz = JigGeometry.RotateTo(line.Direction, Math.PI*.5, XYZ.BasisZ) * offset;
			XYZ xyz2 = hyendPoint + xyz;
			XYZ xyz3 = hyendPoint2 + xyz;
			return Line.CreateBound(xyz2, xyz3);
		}

		public static Arc OffsetArc(Application app, Arc arc, double offset)
		{
			if (arc.Normal.Z > 0.0)
			{
				offset = -offset;
			}
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ hyendPoint2 = arc.GetEndPoint(1);
			XYZ center = arc.Center;
			XYZ xyz = JigGeometry.CalculatMidPoint(arc);
			double num = arc.Radius + offset;
			XYZ xyz2 = (hyendPoint - center).Normalize() * num;
			XYZ xyz3 = (hyendPoint2 - center).Normalize() * num;
			XYZ xyz4 = (xyz - center).Normalize() * num;
			XYZ startPnt = center + xyz2;
			XYZ endPnt = center + xyz3;
			XYZ radianPnt = center + xyz4;
			return app.CreatYJKArc(startPnt, endPnt, radianPnt);
		}

		public static double formatAngle(double angle)
		{
			int num = (int)(angle / Math.PI*2);
			double num2 = angle - (double)num * Math.PI*2;
			if (num2 < 0.0)
			{
				num2 += Math.PI*2;
			}
			return num2;
		}

		public static double getAngle(XYZ ptCenter, XYZ ptOut)
		{
			XYZ xyz = ptOut - ptCenter;
			return JigGeometry.formatAngle(XYZ.BasisX.AngleOnPlaneTo(xyz, XYZ.BasisZ));
		}

		public static double BetweenTheAngles(double dSAngle, double dEAngle, bool range2PI)
		{
			dSAngle = JigGeometry.formatAngle(dSAngle);
			dEAngle = JigGeometry.formatAngle(dEAngle);
			if (Math.Abs(dEAngle - dSAngle) < 1E-05)
			{
				return 0.0;
			}
			if (range2PI && dEAngle < dSAngle)
			{
				dEAngle += Math.PI*2;
			}
			return dEAngle - dSAngle;
		}

		public static double IntersectionAngle(double dSAngle, double dEAngle)
		{
			dSAngle = JigGeometry.formatAngle(dSAngle);
			dEAngle = JigGeometry.formatAngle(dEAngle);
			double num = JigGeometry.formatAngle(Math.Abs(dSAngle - dEAngle));
			if (num > Math.PI)
			{
				num = Math.PI*2 - num;
			}
			return num;
		}

		public static double GetBulge(XYZ SP, XYZ EP, XYZ CenterPt, bool isAnticlockwise)
		{
			XYZ xyz = SP;
			XYZ xyz2 = EP;
			if (!isAnticlockwise)
			{
				xyz = EP;
				xyz2 = SP;
			}
			double num = xyz.DistanceTo(CenterPt);
			double num2 = xyz.DistanceTo(xyz2) / 2.0;
			double num3 = num - Math.Sqrt(num * num - num2 * num2);
			double angle = JigGeometry.getAngle(CenterPt, xyz);
			double angle2 = JigGeometry.getAngle(CenterPt, xyz2);
			double num4 = JigGeometry.BetweenTheAngles(angle, angle2, true);
			if (JigGeometry.IsEqual(num4, Math.PI))
			{
				num3 = num2;
			}
			else if (JigGeometry.LessThan(Math.PI, num4))
			{
				num3 = num * 2.0 - num3;
			}
			double num5 = num3 / num2;
			if (!isAnticlockwise)
			{
				num5 *= -1.0;
			}
			return num5;
		}

		public static void GetRadiusWithBulge(XYZ SP, XYZ EP, double dBulge, ref double dRadius)
		{
			if (JigGeometry.IsEqual(dBulge, 1.0))
			{
				dRadius = SP.DistanceTo(EP) / 2.0;
				return;
			}
			double num = SP.DistanceTo(EP) / 2.0;
			double num2 = Math.Abs(dBulge) * num;
			dRadius = (num * num + num2 * num2) / (num2 * 2.0);
		}

		public static void GetCenterWithBulge(XYZ SP, XYZ EP, double dBulge, ref XYZ ptCenter)
		{
			if (JigGeometry.IsEqual(dBulge, 1.0))
			{
				ptCenter = JigGeometry.CalculatMidPoint(SP, EP);
				return;
			}
			double num = SP.DistanceTo(EP) / 2.0;
			double num2 = Math.Abs(dBulge) * num;
			double num3 = (num * num + num2 * num2) / (num2 * 2.0);
			XYZ xyz = JigGeometry.CalculatMidPoint(SP, EP);
			XYZ xyz2 = (EP - SP).Normalize();
			if (dBulge > 0.0)
			{
				xyz2 = JigGeometry.RotateTo(xyz2, Math.PI*.5, XYZ.BasisZ);
				xyz2 *= num3 - num2;
				ptCenter = xyz + xyz2;
				return;
			}
			xyz2 = JigGeometry.RotateTo(xyz2, -Math.PI*.5, XYZ.BasisZ);
			xyz2 *= num3 - num2;
			ptCenter = xyz + xyz2;
		}

		public static void GetArcInfoWithBulge(XYZ SP, XYZ EP, double dBulge, ref XYZ ptCenter, ref double dRadius, ref double dSAngle, ref double dEAngle)
		{
			JigGeometry.GetCenterWithBulge(SP, EP, dBulge, ref ptCenter);
			dRadius = SP.DistanceTo(ptCenter);
			Math.Atan(1.0 / Math.Abs(dBulge));
			if (dBulge > 0.0)
			{
				dSAngle = JigGeometry.getAngle(ptCenter, SP);
				dEAngle = JigGeometry.getAngle(ptCenter, EP);
				return;
			}
			dSAngle = JigGeometry.getAngle(ptCenter, EP);
			dEAngle = JigGeometry.getAngle(ptCenter, SP);
		}

		public static bool Is_Points_Collinear(XYZ pt1, XYZ pt2, XYZ pt3)
		{
			double num = pt2.X - pt1.X;
			double num2 = pt2.Y - pt1.Y;
			double num3 = pt2.Z - pt1.Z;
			double num4 = pt3.X - pt1.X;
			double num5 = pt3.Y - pt1.Y;
			double num6 = pt3.Z - pt1.Z;
			double num7 = num2 * num6 - num5 * num3;
			double num8 = num4 * num3 - num * num6;
			double num9 = num * num5 - num4 * num2;
			return JigGeometry.IsEqual(num7 * num7 + num8 * num8 + num9 * num9, 0.0);
		}

		public static bool Is_Point_OnSegment(XYZ ptSOfLine, XYZ ptEOfLine, XYZ pt)
		{
			double x = ptSOfLine.X;
			double y = ptSOfLine.Y;
			double z = ptSOfLine.Z;
			double x2 = ptEOfLine.X;
			double y2 = ptEOfLine.Y;
			double z2 = ptEOfLine.Z;
			return ((JigGeometry.Lessthan_Or_Equal(x, pt.X) && JigGeometry.Lessthan_Or_Equal(pt.X, x2)) || (JigGeometry.Lessthan_Or_Equal(x2, pt.X) && JigGeometry.Lessthan_Or_Equal(pt.X, x))) && ((JigGeometry.Lessthan_Or_Equal(y, pt.Y) && JigGeometry.Lessthan_Or_Equal(pt.Y, y2)) || (JigGeometry.Lessthan_Or_Equal(y2, pt.Y) && JigGeometry.Lessthan_Or_Equal(pt.Y, y))) && ((JigGeometry.Lessthan_Or_Equal(z, pt.Z) && JigGeometry.Lessthan_Or_Equal(pt.Z, z2)) || (JigGeometry.Lessthan_Or_Equal(z2, pt.Z) && JigGeometry.Lessthan_Or_Equal(pt.Z, z))) && JigGeometry.Is_Points_Collinear(ptSOfLine, ptEOfLine, pt);
		}

		public static bool Is_Point_OnSegment(XYZ ptSOfArc, XYZ ptEOfArc, XYZ ptCenterOfArc, XYZ normal, XYZ pt)
		{
			if (normal.Z < 0.0)
			{
				XYZ xyz = ptSOfArc;
				ptSOfArc = ptEOfArc;
				ptEOfArc = xyz;
			}
			double val = ptSOfArc.DistanceTo(ptCenterOfArc);
			double val2 = ptEOfArc.DistanceTo(ptCenterOfArc);
			if (!JigGeometry.IsEqual(val, val2))
			{
				return false;
			}
			double val3 = pt.DistanceTo(ptCenterOfArc);
			if (!JigGeometry.IsEqual(val, val3))
			{
				return false;
			}
			double angle = JigGeometry.getAngle(ptCenterOfArc, ptSOfArc);
			double angle2 = JigGeometry.getAngle(ptCenterOfArc, pt);
			double angle3 = JigGeometry.getAngle(ptCenterOfArc, pt);
			double num = JigGeometry.BetweenTheAngles(angle, angle2, true);
			double num2 = JigGeometry.BetweenTheAngles(angle2, angle3, true);
			return JigGeometry.IsEqual(JigGeometry.BetweenTheAngles(angle, angle3, true), num + num2);
		}

		protected static List<Curve> ExtendEndsWithCurve(Curve curve, Application revitApp)
		{
			List<Curve> list = new List<Curve>();
			if (!curve.IsBound)
			{
				list.Add(curve);
				return list;
			}
			Line line = curve as Line;
			if (null != line)
			{
				XYZ hyendPoint = line.GetEndPoint(0);
				XYZ hyendPoint2 = line.GetEndPoint(1);
				Line item = YJKLineEx.YJKGetUnBound(hyendPoint, hyendPoint2 - hyendPoint);
				list.Add(item);
				return list;
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				XYZ center = arc.Center;
				double radius = arc.Radius;
				XYZ xyz = center + XYZ.BasisX * radius;
				XYZ radianPnt = center + XYZ.BasisY * radius;
				XYZ xyz2 = center + -XYZ.BasisX * radius;
				XYZ radianPnt2 = center + -XYZ.BasisY * radius;
				Arc item2 = revitApp.CreatYJKArc(xyz, xyz2, radianPnt);
				list.Add(item2);
				Arc item3 = revitApp.CreatYJKArc(xyz2, xyz, radianPnt2);
				list.Add(item3);
				return list;
			}
			return list;
		}

		public static XYZ IntersectWithTwoCurves(Curve curve1, Curve curve2, XYZ curNode, bool extendCurve1, bool extendCurve2, Application revitApp)
		{
			List<Curve> list = new List<Curve>();
			if (extendCurve1)
			{
				list = JigGeometry.ExtendEndsWithCurve(curve1, revitApp);
			}
			else
			{
				list.Add(curve1);
			}
			List<Curve> list2 = new List<Curve>();
			if (extendCurve2)
			{
				list2 = JigGeometry.ExtendEndsWithCurve(curve2, revitApp);
			}
			else
			{
				list2.Add(curve2);
			}
			List<XYZ> list3 = new List<XYZ>();
			foreach (Curve curve3 in list)
			{
				foreach (Curve curve4 in list2)
				{
					IntersectionResultArray intersectionResultArray;
                    if (curve3.Intersect(curve4, out intersectionResultArray) == SetComparisonResult.Overlap)
					{
						foreach (object obj in intersectionResultArray)
						{
							IntersectionResult intersectionResult = (IntersectionResult)obj;
							list3.Add(intersectionResult.XYZPoint);
						}
					}
				}
			}
			double num = double.MaxValue;
			XYZ result = null;
			foreach (XYZ xyz in list3)
			{
				double num2 = curNode.DistanceTo(xyz);
				if (num2 < num)
				{
					num = num2;
					result = xyz;
				}
			}
			return result;
		}

		public static JigGeometry.OverlapType IsOverlapOfTwoLine(XYZ ptS1, XYZ ptE1, XYZ ptS2, XYZ ptE2, ref XYZ ptS, ref XYZ ptE)
		{
			if ((ptS1.IsAlmostEqualTo(ptS2) && ptE1.IsAlmostEqualTo(ptE2)) || (ptS1.IsAlmostEqualTo(ptE2) && ptE1.IsAlmostEqualTo(ptS2)))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_Equality;
			}
			if (JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptS2) && JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptE2))
			{
				ptS = ptS2;
				ptE = ptE2;
				return JigGeometry.OverlapType._OT_FirstIncludeSecond;
			}
			if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptS1) && JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptE1))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_SecondIncludeFirst;
			}
			if (JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptS2))
			{
				if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptS1))
				{
					ptS = ptS2;
					ptE = ptS1;
					if (!ptS2.IsAlmostEqualTo(ptS1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
				else if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptE1))
				{
					ptS = ptS2;
					ptE = ptE1;
					if (!ptS2.IsAlmostEqualTo(ptE1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
			}
			else if (JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptE2))
			{
				if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptS1))
				{
					ptS = ptE2;
					ptE = ptS1;
					if (!ptE2.IsAlmostEqualTo(ptS1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
				else if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptE1))
				{
					ptS = ptE2;
					ptE = ptE1;
					if (!ptE2.IsAlmostEqualTo(ptE1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
			}
			return JigGeometry.OverlapType._OT_None;
		}

		public static JigGeometry.OverlapType MergerOfTwoLine(XYZ ptS1, XYZ ptE1, XYZ ptS2, XYZ ptE2, ref XYZ ptS, ref XYZ ptE)
		{
			if ((ptS1.IsAlmostEqualTo(ptS2) && ptE1.IsAlmostEqualTo(ptE2)) || (ptS1.IsAlmostEqualTo(ptE2) && ptE1.IsAlmostEqualTo(ptS2)))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_Equality;
			}
			if (JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptS2) && JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptE2))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_FirstIncludeSecond;
			}
			if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptS1) && JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptE1))
			{
				ptS = ptS2;
				ptE = ptE2;
				return JigGeometry.OverlapType._OT_SecondIncludeFirst;
			}
			if (JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptS2))
			{
				if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptS1))
				{
					ptS = ptE2;
					ptE = ptE1;
					if (!ptS2.IsAlmostEqualTo(ptS1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
				else if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptE1))
				{
					ptS = ptE2;
					ptE = ptS1;
					if (!ptS2.IsAlmostEqualTo(ptE1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
			}
			else if (JigGeometry.Is_Point_OnSegment(ptS1, ptE1, ptE2))
			{
				if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptS1))
				{
					ptS = ptS2;
					ptE = ptE1;
					if (!ptE2.IsAlmostEqualTo(ptS1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
				else if (JigGeometry.Is_Point_OnSegment(ptS2, ptE2, ptE1))
				{
					ptS = ptS2;
					ptE = ptS1;
					if (!ptE2.IsAlmostEqualTo(ptE1))
					{
						return JigGeometry.OverlapType._OT_Part;
					}
					return JigGeometry.OverlapType._OT_Linked;
				}
			}
			return JigGeometry.OverlapType._OT_None;
		}

		private static bool IsCoverAngle(double sAngle, double eAngle, double testAngle)
		{
			double val = JigGeometry.BetweenTheAngles(sAngle, eAngle, true);
			double num = JigGeometry.BetweenTheAngles(sAngle, testAngle, true);
			double num2 = JigGeometry.BetweenTheAngles(testAngle, eAngle, true);
			return JigGeometry.IsEqual(val, num + num2);
		}

		public static JigGeometry.OverlapType IsOverlapOfTwoArc(XYZ ptS1, XYZ ptE1, XYZ ptCenter1, XYZ ptS2, XYZ ptE2, XYZ ptCenter2, ref XYZ ptS, ref XYZ ptE)
		{
			if (!ptCenter1.IsAlmostEqualTo(ptCenter2))
			{
				return JigGeometry.OverlapType._OT_None;
			}
			double val = ptS1.DistanceTo(ptCenter1);
			double val2 = ptS2.DistanceTo(ptCenter2);
			if (!JigGeometry.IsEqual(val, val2))
			{
				return JigGeometry.OverlapType._OT_None;
			}
			double angle = JigGeometry.getAngle(ptCenter1, ptS1);
			double angle2 = JigGeometry.getAngle(ptCenter1, ptE1);
			double angle3 = JigGeometry.getAngle(ptCenter2, ptS2);
			double angle4 = JigGeometry.getAngle(ptCenter2, ptE2);
			if (JigGeometry.IsEqual(angle, angle3) && JigGeometry.IsEqual(angle2, angle4))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_Equality;
			}
			if (JigGeometry.IsEqual(angle, angle4) && JigGeometry.IsEqual(angle2, angle3))
			{
				return JigGeometry.OverlapType._OT_Linked;
			}
			if (JigGeometry.IsCoverAngle(angle, angle2, angle3) && JigGeometry.IsCoverAngle(angle, angle2, angle4))
			{
				ptS = ptS2;
				ptE = ptE2;
				return JigGeometry.OverlapType._OT_FirstIncludeSecond;
			}
			if (JigGeometry.IsCoverAngle(angle3, angle4, angle) && JigGeometry.IsCoverAngle(angle3, angle4, angle2))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_SecondIncludeFirst;
			}
			if (JigGeometry.IsCoverAngle(angle3, angle4, angle))
			{
				ptS = ptS1;
				ptE = ptE2;
				if (JigGeometry.IsEqual(angle, angle4))
				{
					return JigGeometry.OverlapType._OT_Linked;
				}
				return JigGeometry.OverlapType._OT_Part;
			}
			else
			{
				if (!JigGeometry.IsCoverAngle(angle, angle2, angle3))
				{
					return JigGeometry.OverlapType._OT_None;
				}
				ptS = ptS2;
				ptE = ptE1;
				if (JigGeometry.IsEqual(angle3, angle2))
				{
					return JigGeometry.OverlapType._OT_Linked;
				}
				return JigGeometry.OverlapType._OT_Part;
			}
		}

		public static JigGeometry.OverlapType MergerOfTwoArc(XYZ ptS1, XYZ ptE1, XYZ ptCenter1, XYZ ptS2, XYZ ptE2, XYZ ptCenter2, ref XYZ ptS, ref XYZ ptE)
		{
			if (!ptCenter1.IsAlmostEqualTo(ptCenter2))
			{
				return JigGeometry.OverlapType._OT_None;
			}
			double val = ptS1.DistanceTo(ptCenter1);
			double val2 = ptS2.DistanceTo(ptCenter2);
			if (!JigGeometry.IsEqual(val, val2))
			{
				return JigGeometry.OverlapType._OT_None;
			}
			double angle = JigGeometry.getAngle(ptCenter1, ptS1);
			double angle2 = JigGeometry.getAngle(ptCenter1, ptE1);
			double angle3 = JigGeometry.getAngle(ptCenter2, ptS2);
			double angle4 = JigGeometry.getAngle(ptCenter2, ptE2);
			if (JigGeometry.IsEqual(angle, angle3) && JigGeometry.IsEqual(angle2, angle4))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_Equality;
			}
			if (JigGeometry.IsEqual(angle, angle4))
			{
				ptS = ptS2;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_Linked;
			}
			if (JigGeometry.IsEqual(angle2, angle3))
			{
				ptS = ptS1;
				ptE = ptE2;
				return JigGeometry.OverlapType._OT_Linked;
			}
			if (JigGeometry.IsCoverAngle(angle, angle2, angle3) && JigGeometry.IsCoverAngle(angle, angle2, angle4))
			{
				ptS = ptS1;
				ptE = ptE1;
				return JigGeometry.OverlapType._OT_FirstIncludeSecond;
			}
			if (JigGeometry.IsCoverAngle(angle3, angle4, angle) && JigGeometry.IsCoverAngle(angle3, angle4, angle2))
			{
				ptS = ptS2;
				ptE = ptE2;
				return JigGeometry.OverlapType._OT_SecondIncludeFirst;
			}
			if (JigGeometry.IsCoverAngle(angle3, angle4, angle))
			{
				ptS = ptS2;
				ptE = ptE1;
				if (JigGeometry.IsEqual(angle, angle4))
				{
					return JigGeometry.OverlapType._OT_Linked;
				}
				return JigGeometry.OverlapType._OT_Part;
			}
			else
			{
				if (!JigGeometry.IsCoverAngle(angle, angle2, angle3))
				{
					return JigGeometry.OverlapType._OT_None;
				}
				ptS = ptS1;
				ptE = ptE2;
				if (JigGeometry.IsEqual(angle3, angle2))
				{
					return JigGeometry.OverlapType._OT_Linked;
				}
				return JigGeometry.OverlapType._OT_Part;
			}
		}

		private static bool IsOverlap(XYZ ptS1, XYZ ptE1, double bugle1, XYZ ptS2, XYZ ptE2, double bugle2)
		{
			if (JigGeometry.IsEqual(bugle1, 0.0) && JigGeometry.IsEqual(bugle2, 0.0))
			{
				if (ptS1.IsAlmostEqualTo(ptE2, 0.0001) && ptE1.IsAlmostEqualTo(ptS2, 0.0001))
				{
					return true;
				}
			}
			else if (!JigGeometry.IsEqual(bugle1, 0.0) && !JigGeometry.IsEqual(bugle2, 0.0) && ptS1.IsAlmostEqualTo(ptE2, 0.0001) && ptE1.IsAlmostEqualTo(ptS2, 0.0001) && JigGeometry.IsEqual(bugle1, -bugle2))
			{
				return true;
			}
			return false;
		}

		public static void ConvertToSimpleClosedPolylineAndSimpleCurve(List<XYZ> points, List<double> bulges, ref List<List<XYZ>> simplePolysPoint, ref List<List<double>> simplePolysBulge, ref List<JigEdgeInfo> simpleCurves)
		{
			if (points.Count != bulges.Count)
			{
				return;
			}
			int i = 0;
			if (points.Count < 3)
			{
				while (i < points.Count)
				{
					XYZ startPoint = points[i];
					XYZ endPoint;
					if (i == points.Count - 1)
					{
						endPoint = points[0];
					}
					else
					{
						endPoint = points[i + 1];
					}
					double bulge = bulges[i];
					JigEdgeInfo item = new JigEdgeInfo(startPoint, endPoint, bulge);
					simpleCurves.Add(item);
					i++;
				}
				return;
			}
			bool flag = false;
			for (i = 0; i < points.Count; i++)
			{
				XYZ xyz = points[i];
				XYZ xyz2;
				if (i == points.Count - 1)
				{
					xyz2 = points[0];
				}
				else
				{
					xyz2 = points[i + 1];
				}
				if (!xyz.IsAlmostEqualTo(xyz2, 0.0001))
				{
					double num = bulges[i];
					flag = false;
					for (int j = i + 1; j < points.Count; j++)
					{
						XYZ xyz3 = points[j];
						XYZ xyz4;
						if (j == points.Count - 1)
						{
							xyz4 = points[0];
						}
						else
						{
							xyz4 = points[j + 1];
						}
						if (!xyz3.IsAlmostEqualTo(xyz4, 0.0001))
						{
							double bugle = bulges[j];
							if (JigGeometry.IsOverlap(xyz, xyz2, num, xyz3, xyz4, bugle))
							{
								JigEdgeInfo item2 = new JigEdgeInfo(xyz, xyz2, num);
								simpleCurves.Add(item2);
								List<XYZ> list = new List<XYZ>();
								List<XYZ> points2 = new List<XYZ>();
								List<double> list2 = new List<double>();
								List<double> bulges2 = new List<double>();
								if (i >= 0)
								{
									list = points.GetRange(0, i + 1);
									list2 = bulges.GetRange(0, i);
									if (j < points.Count - 2)
									{
										List<XYZ> range = points.GetRange(j + 2, points.Count - (j + 2));
										list.InsertRange(list.Count, range);
										List<double> range2 = bulges.GetRange(j + 1, bulges.Count - (j + 1));
										list2.InsertRange(list2.Count, range2);
									}
									else if (j == points.Count - 1)
									{
										list.RemoveAt(list.Count - 1);
									}
									else
									{
										list2.Add(bulges[bulges.Count - 1]);
									}
								}
								if (j < points.Count - 1 && j > i + 1)
								{
									points2 = points.GetRange(i + 1, j - (i + 1));
									bulges2 = bulges.GetRange(i + 1, j - (i + 1));
								}
								JigGeometry.ConvertToSimpleClosedPolylineAndSimpleCurve(list, list2, ref simplePolysPoint, ref simplePolysBulge, ref simpleCurves);
								JigGeometry.ConvertToSimpleClosedPolylineAndSimpleCurve(points2, bulges2, ref simplePolysPoint, ref simplePolysBulge, ref simpleCurves);
								flag = true;
								break;
							}
						}
					}
					if (flag)
					{
						break;
					}
				}
			}
			if (!flag && points.Count > 1)
			{
				simplePolysPoint.Add(points);
				simplePolysBulge.Add(bulges);
			}
		}

		public static bool GetFittingPolyline(List<XYZ> polylinePoints, List<double> polylineBulge, ref List<XYZ> fittingPolyline, double fitSpace)
		{
			if (polylinePoints.Count != polylineBulge.Count)
			{
				return false;
			}
			if (polylinePoints.Count < 2)
			{
				return false;
			}
			fittingPolyline.Add(polylinePoints[0]);
			for (int i = 0; i < polylinePoints.Count; i++)
			{
				XYZ xyz;
				XYZ xyz2;
				if (i == polylinePoints.Count - 1)
				{
					xyz = polylinePoints[i];
					xyz2 = polylinePoints[0];
				}
				else
				{
					xyz = polylinePoints[i];
					xyz2 = polylinePoints[i + 1];
				}
				if (!xyz.IsAlmostEqualTo(xyz2, 0.0001))
				{
					if (JigGeometry.IsEqual(polylineBulge[i], 0.0))
					{
						if (i + 1 < polylinePoints.Count)
						{
							fittingPolyline.Add(polylinePoints[i + 1]);
						}
					}
					else
					{
						XYZ xyz3 = null;
						JigGeometry.GetCenterWithBulge(xyz, xyz2, polylineBulge[i], ref xyz3);
						double num = xyz3.DistanceTo(xyz);
						double angle = JigGeometry.getAngle(xyz3, xyz);
						double angle2 = JigGeometry.getAngle(xyz3, xyz2);
						double num2 = JigGeometry.BetweenTheAngles(angle, angle2, true) * num;
						int num3 = (int)(num2 / fitSpace);
						double num4 = num2 / (double)num3 / num;
						for (int j = 0; j <= num3; j++)
						{
							double angle3 = angle + num4 * (double)j;
							XYZ xyz4 = new XYZ(1.0, 0.0, 0.0);
							xyz4 *= num;
							xyz4 = JigGeometry.RotateTo(xyz4, angle3, XYZ.BasisZ);
							XYZ item = xyz3 + xyz4;
							fittingPolyline.Add(item);
						}
					}
				}
			}
			return true;
		}

		public static int PointInPloygon(List<XYZ> vecPolypt, XYZ pt)
		{
			List<XYZ> range = vecPolypt.GetRange(0, vecPolypt.Count);
			if (range.Count < 3)
			{
				return -1;
			}
			XYZ xyz = range[0];
			XYZ xyz2 = range[range.Count - 1];
			if (xyz != xyz2)
			{
				range.Add(xyz);
			}
			int num = 0;
			List<XYZ> list = new List<XYZ>();
			XYZ xyz3 = new XYZ(0.0, 0.0, 0.0) - pt;
			for (int i = 0; i < range.Count; i++)
			{
				XYZ xyz4 = range[i];
				xyz4 += xyz3;
				list.Add(xyz4);
			}
			XYZ xyz5 = pt + xyz3;
			int num2 = JigGeometry.Greaterthan_Or_Equal(list[0].X, 0.0) ? (JigGeometry.Greaterthan_Or_Equal(list[0].Y, 0.0) ? 0 : 3) : (JigGeometry.Greaterthan_Or_Equal(list[0].Y, 0.0) ? 1 : 2);
			for (int i = 1; i < list.Count; i++)
			{
				XYZ xyz6 = list[i - 1];
				XYZ xyz7 = list[i];
				if (xyz5.IsAlmostEqualTo(xyz6, 0.0001))
				{
					return 0;
				}
				XYZ xyz8 = new XYZ(xyz6.X, xyz6.Y, xyz6.Z);
				XYZ xyz9 = new XYZ(xyz7.X, xyz7.Y, xyz7.Z);
				xyz8 = xyz8.Normalize();
				xyz9 = xyz9.Normalize();
				double num3 = xyz9.Y * xyz8.X - xyz9.X * xyz8.Y;
				if (Math.Abs(num3) < 0.0001 && xyz8.X * xyz9.X <= 0.0001 && xyz8.Y * xyz9.Y <= 0.0001)
				{
					return 0;
				}
				int num4 = JigGeometry.Greaterthan_Or_Equal(xyz7.X, 0.0) ? (JigGeometry.Greaterthan_Or_Equal(xyz7.Y, 0.0) ? 0 : 3) : (JigGeometry.Greaterthan_Or_Equal(xyz7.Y, 0.0) ? 1 : 2);
				if (num4 == (num2 + 1) % 4)
				{
					num++;
				}
				else if (num4 == (num2 + 2) % 4)
				{
					if (num3 > 0.0)
					{
						num += 2;
					}
					else
					{
						num -= 2;
					}
				}
				else if (num4 == (num2 + 3) % 4)
				{
					num--;
				}
				num2 = num4;
			}
			if (num == 0)
			{
				return -1;
			}
			if (Math.Abs(num) == 4)
			{
				return 1;
			}
			return 0;
		}

		public const double _epsDouble = 1E-09;

		public const double _epsPoint = 0.0001;

		public const double _epsAngle = 0.0001;

		public enum OverlapType
		{
			_OT_None,
			_OT_Equality,
			_OT_FirstIncludeSecond,
			_OT_SecondIncludeFirst,
			_OT_Part,
			_OT_Linked
		}
	}
}
